home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / JFC.bin / MetalTabbedPaneUI.java < prev    next >
Text File  |  1998-06-30  |  22KB  |  661 lines

  1. /*
  2.  * @(#)MetalTabbedPaneUI.java    1.14 98/04/10
  3.  *
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  *
  19.  */
  20.  
  21. package com.sun.java.swing.plaf.metal;
  22.  
  23. import com.sun.java.swing.*;
  24. import com.sun.java.swing.event.*;
  25. import java.awt.*;
  26. import java.awt.event.*;
  27. import com.sun.java.swing.plaf.*;
  28. import java.io.Serializable; 
  29. import com.sun.java.swing.plaf.basic.BasicTabbedPaneUI;
  30.  
  31. /**
  32.  * The Metal subclass of BasicTabbedPaneUI.
  33.  * <p>
  34.  * Warning: serialized objects of this class will not be compatible with
  35.  * future swing releases.  The current serialization support is appropriate
  36.  * for short term storage or RMI between Swing1.0 applications.  It will
  37.  * not be possible to load serialized Swing1.0 objects with future releases
  38.  * of Swing.  The JDK1.2 release of Swing will be the compatibility
  39.  * baseline for the serialized form of Swing objects.
  40.  *
  41.  * @version 1.14 04/10/98
  42.  * @author Tom Santos
  43.  */
  44.  
  45. public class MetalTabbedPaneUI extends BasicTabbedPaneUI {
  46.  
  47.     protected static Insets tabsOnTopTabAreaInsets = new Insets(4,2,0,6);
  48.     protected static Insets tabsOnLeftTabAreaInsets = new Insets(6,4,0,0);
  49.     protected static Insets tabsOnBottomTabAreaInsets = new Insets(0,2,4,6);
  50.     protected static Insets tabsOnRightTabAreaInsets = new Insets(0,0,6,4);
  51.  
  52.     protected int minTabWidth = 40;
  53.     protected Color selectColor;
  54.     protected Color selectHighlight;
  55.  
  56.     public static ComponentUI createUI( JComponent x ) {
  57.         return new MetalTabbedPaneUI();
  58.     }    
  59.  
  60.  
  61.     protected void installDefaults( JComponent c ) {
  62.         JTabbedPane pane = (JTabbedPane)c;
  63.         super.installDefaults(c);
  64.  
  65.         selectColor = UIManager.getColor("TabbedPane.selected");
  66.         selectHighlight = UIManager.getColor("TabbedPane.selectHighlight");
  67.     }
  68.  
  69.  
  70.     protected void paintTabBorder( Graphics g, JTabbedPane pane, int tabPlacement,
  71.                                    int tabIndex, int x, int y, int w, int h, 
  72.                                    boolean isSelected) {
  73.         int bottom = y + (h-1);
  74.         int right = x + (w-1);
  75.  
  76.         switch ( tabPlacement ) {
  77.         case LEFT:
  78.             paintLeftTabBorder(pane, tabIndex, g, x, y, w, h, bottom, right, isSelected);
  79.             break;
  80.         case BOTTOM:
  81.             paintBottomTabBorder(pane, tabIndex, g, x, y, w, h, bottom, right, isSelected);
  82.             break;
  83.         case RIGHT:
  84.             paintRightTabBorder(pane, tabIndex, g, x, y, w, h, bottom, right, isSelected);
  85.             break;
  86.         case TOP:
  87.         default:
  88.             paintTopTabBorder(pane, tabIndex, g, x, y, w, h, bottom, right, isSelected);
  89.         }
  90.     }
  91.  
  92.  
  93.     protected void paintTopTabBorder( JTabbedPane pane, int tabIndex, Graphics g, 
  94.                                       int x, int y, int w, int h,
  95.                                       int btm, int rght,
  96.                                       boolean isSelected ) {
  97.         int currentRun = getRunForTab( pane, pane.getTabCount(), tabIndex );
  98.         int lastIndex = lastIndexInRun( currentRun, pane.getTabCount() );
  99.         int firstIndex = tabRuns[ currentRun ];
  100.  
  101.         //
  102.         // Paint Gap
  103.         //
  104.  
  105.         if ( shouldFillGap( pane, currentRun, tabIndex, x, y ) ) {
  106.             g.translate( x, y );
  107.  
  108.             g.setColor( getColorForGap( pane, currentRun, x, y + 1 ) );
  109.             g.fillRect( 1, 0, 5, 3 );
  110.             g.fillRect( 1, 3, 2, 2 );
  111.  
  112.             g.translate( -x, -y );
  113.         }
  114.  
  115.         g.translate( x, y );
  116.  
  117.         int bottom = h - 1;
  118.         int right = w - 1;
  119.  
  120.         //
  121.         // Paint Border
  122.         //
  123.  
  124.         g.setColor( tabDarkShadow );
  125.  
  126.         // Paint slant
  127.         g.drawLine( 1,5 , 6,0 );
  128.  
  129.         // Paint top
  130.         g.drawLine( 6,0 , right,0 );
  131.  
  132.         // Paint right
  133.         if ( tabIndex == lastIndex ) {
  134.             g.drawLine( right,1 , right,bottom );
  135.         }
  136.  
  137.         // Paint left
  138.         if ( tabIndex != tabRuns[ runCount - 1 ] ) {
  139.             g.drawLine( 0,0 , 0,bottom );
  140.         } else {
  141.             g.drawLine( 0,6 , 0,bottom );
  142.         }
  143.  
  144.  
  145.         //
  146.         // Paint Highlight
  147.         //
  148.  
  149.         g.setColor( isSelected ? selectHighlight : tabHighlight );
  150.  
  151.         // Paint slant
  152.         g.drawLine( 1,6 , 6,1 );
  153.  
  154.         // Paint top
  155.         g.drawLine( 6,1 , right,1 );
  156.  
  157.         // Paint left
  158.         g.drawLine( 1,6 , 1,bottom );
  159.  
  160.         if ( tabIndex == firstIndex && tabIndex != tabRuns[ runCount - 1 ] ) {
  161.             g.setColor( pane.getSelectedIndex() == tabRuns[ currentRun + 1 ] ? selectHighlight : tabHighlight );
  162.             g.drawLine( 1,0 , 1,4 );
  163.         }
  164.  
  165.         g.translate( -x, -y );
  166.     }
  167.  
  168.     protected boolean shouldFillGap( JTabbedPane pane, int currentRun, int tabIndex, int x, int y ) {
  169.         boolean result = false;
  170.  
  171.         if ( currentRun == runCount - 2 ) {  // If it's the second to last row.
  172.             Rectangle lastTabBounds = getTabBounds( pane, pane.getTabCount() - 1 );
  173.             int lastTabRight = lastTabBounds.x + lastTabBounds.width - 1;
  174.             if ( lastTabRight > getTabBounds( pane, tabIndex ).x + 2 ) {
  175.                 return true;
  176.             }
  177.         } else {
  178.             result = currentRun != runCount - 1;
  179.         }
  180.  
  181.         return result;
  182.     }
  183.  
  184.     protected Color getColorForGap( JTabbedPane pane, int currentRun, int x, int y ) {
  185.         final int shadowWidth = 4;
  186.         int selectedIndex = pane.getSelectedIndex();
  187.         int startIndex = tabRuns[ currentRun + 1 ];
  188.         int endIndex = lastIndexInRun( currentRun + 1, pane.getTabCount() );
  189.         int tabOverGap = -1;
  190.         // Check each tab in the row that is 'on top' of this row
  191.         for ( int i = startIndex; i <= endIndex; ++i ) {
  192.             Rectangle tabBounds = getTabBounds( pane, i );
  193.             int tabLeft = tabBounds.x;
  194.             int tabRight = (tabBounds.x + tabBounds.width) - 1;
  195.             // Check to see if this tab is over the gap
  196.             if ( tabLeft + 1 < x && tabRight - shadowWidth > x ) {
  197.                 return selectedIndex == i ? selectColor : pane.getBackgroundAt( i );
  198.             }
  199.         }
  200.  
  201.         return pane.getBackground();
  202.     }
  203.  
  204.     protected void paintLeftTabBorder( JTabbedPane pane, int tabIndex, Graphics g, 
  205.                                        int x, int y, int w, int h,
  206.                                        int btm, int rght,
  207.                                        boolean isSelected ) {
  208.         int currentRun = getRunForTab( pane, pane.getTabCount(), tabIndex );
  209.         int lastIndex = lastIndexInRun( currentRun, pane.getTabCount() );
  210.         int firstIndex = tabRuns[ currentRun ];
  211.  
  212.         g.translate( x, y );
  213.  
  214.         int bottom = h - 1;
  215.         int right = w - 1;
  216.  
  217.         //
  218.         // Paint part of the tab above
  219.         //
  220.  
  221.         if ( tabIndex != firstIndex ) {
  222.             g.setColor( pane.getSelectedIndex() == tabIndex - 1 ?
  223.                         selectColor :
  224.                         pane.getBackgroundAt( tabIndex - 1 ) );
  225.             g.fillRect( 2, 0, 4, 3 );
  226.             g.drawLine( 2, 3, 2, 3 );
  227.         }
  228.  
  229.  
  230.         //
  231.         // Paint Highlight
  232.         //
  233.  
  234.         g.setColor( isSelected ? selectHighlight : tabHighlight );
  235.  
  236.         // Paint slant
  237.         g.drawLine( 1, 6, 6, 1 );
  238.  
  239.         // Paint top
  240.         g.drawLine( 6, 1, right, 1 );
  241.  
  242.         // Paint left
  243.         g.drawLine( 1, 6, 1, bottom );
  244.  
  245.         if ( tabIndex != firstIndex ) {
  246.             g.setColor( pane.getSelectedIndex() == tabIndex - 1 ?
  247.                         selectHighlight :
  248.                         tabHighlight );
  249.             g.drawLine( 1, 0, 1, 4 );
  250.         }
  251.  
  252.         //
  253.         // Paint Border
  254.         //
  255.  
  256.         g.setColor( tabDarkShadow );
  257.  
  258.         // Paint slant
  259.         g.drawLine( 1, 5, 6, 0 );
  260.  
  261.         // Paint top
  262.         g.drawLine( 6, 0, right, 0 );
  263.  
  264.         // Paint left
  265.         if ( tabIndex != firstIndex ) {
  266.             g.drawLine( 0, 0, 0, bottom );
  267.         } else {
  268.             g.drawLine( 0, 6, 0, bottom );
  269.         }
  270.  
  271.         // Paint bottom
  272.         if ( tabIndex == lastIndex ) {
  273.             g.drawLine( 0, bottom, right, bottom );
  274.         }
  275.  
  276.         g.translate( -x, -y );
  277.     }
  278.  
  279.  
  280.     protected void paintBottomTabBorder( JTabbedPane pane, int tabIndex, Graphics g, 
  281.                                          int x, int y, int w, int h,
  282.                                          int btm, int rght,
  283.                                          boolean isSelected ) {
  284.         int currentRun = getRunForTab( pane, pane.getTabCount(), tabIndex );
  285.         int lastIndex = lastIndexInRun( currentRun, pane.getTabCount() );
  286.         int firstIndex = tabRuns[ currentRun ];
  287.  
  288.         int bottom = h - 1;
  289.         int right = w - 1;
  290.  
  291.         //
  292.         // Paint Gap
  293.         //
  294.  
  295.         if ( shouldFillGap( pane, currentRun, tabIndex, x, y ) ) {
  296.             g.translate( x, y );
  297.  
  298.             g.setColor( getColorForGap( pane, currentRun, x, y ) );
  299.             g.fillRect( 1, bottom - 4, 3, 5 );
  300.             g.fillRect( 4, bottom - 1, 2, 2 );
  301.  
  302.             g.translate( -x, -y );
  303.         }
  304.  
  305.         g.translate( x, y );
  306.  
  307.  
  308.         //
  309.         // Paint Border
  310.         //
  311.  
  312.         g.setColor( tabDarkShadow );
  313.  
  314.         // Paint slant
  315.         g.drawLine( 1, bottom - 5, 6, bottom );
  316.  
  317.         // Paint bottom
  318.         g.drawLine( 6, bottom, right, bottom );
  319.  
  320.         // Paint right
  321.         if ( tabIndex == lastIndex ) {
  322.             g.drawLine( right, 0, right, bottom );
  323.         }
  324.  
  325.         // Paint left
  326.         if ( tabIndex != tabRuns[ runCount - 1 ] ) {
  327.             g.drawLine( 0, 0, 0, bottom );
  328.         } else {
  329.             g.drawLine( 0, 0, 0, bottom - 6 );
  330.         }
  331.  
  332.  
  333.         //
  334.         // Paint Highlight
  335.         //
  336.  
  337.         g.setColor( isSelected ? selectHighlight : tabHighlight );
  338.  
  339.         // Paint slant
  340.         g.drawLine( 1, bottom - 6, 6, bottom - 1 );
  341.  
  342.         // Paint left
  343.         g.drawLine( 1, 0, 1, bottom - 6 );
  344.  
  345.         if ( tabIndex == firstIndex && tabIndex != tabRuns[ runCount - 1 ] ) {
  346.             g.setColor( pane.getSelectedIndex() == tabRuns[ currentRun + 1 ] ? selectHighlight : tabHighlight );
  347.             g.drawLine( 1, bottom - 4, 1, bottom );
  348.         }
  349.  
  350.         g.translate( -x, -y );
  351.     }
  352.  
  353.     protected void paintRightTabBorder( JTabbedPane pane, int tabIndex, Graphics g, 
  354.                                         int x, int y, int w, int h,
  355.                                         int btm, int rght,
  356.                                         boolean isSelected ) {
  357.         int currentRun = getRunForTab( pane, pane.getTabCount(), tabIndex );
  358.         int lastIndex = lastIndexInRun( currentRun, pane.getTabCount() );
  359.         int firstIndex = tabRuns[ currentRun ];
  360.  
  361.         g.translate( x, y );
  362.  
  363.         int bottom = h - 1;
  364.         int right = w - 1;
  365.  
  366.         //
  367.         // Paint part of the tab above
  368.         //
  369.  
  370.         if ( tabIndex != firstIndex ) {
  371.             g.setColor( pane.getSelectedIndex() == tabIndex - 1 ?
  372.                         selectColor :
  373.                         pane.getBackgroundAt( tabIndex - 1 ) );
  374.             g.fillRect( right - 5, 0, 5, 3 );
  375.             g.fillRect( right - 2, 3, 2, 2 );
  376.         }
  377.  
  378.  
  379.         //
  380.         // Paint Highlight
  381.         //
  382.  
  383.         g.setColor( isSelected ? selectHighlight : tabHighlight );
  384.  
  385.         // Paint slant
  386.         g.drawLine( right - 6, 1, right - 1, 6 );
  387.  
  388.         // Paint top
  389.         g.drawLine( 0, 1, right - 6, 1 );
  390.  
  391.         // Paint left
  392.         g.drawLine( 0, 1, 0, bottom );
  393.  
  394.  
  395.         //
  396.         // Paint Border
  397.         //
  398.  
  399.         g.setColor( tabDarkShadow );
  400.  
  401.         // Paint slant
  402.         g.drawLine( right - 6, 0, right, 6 );
  403.  
  404.         // Paint top
  405.         g.drawLine( 0, 0, right - 6, 0 );
  406.  
  407.         // Paint right
  408.         if ( tabIndex != firstIndex ) {
  409.             g.drawLine( right, 0, right, bottom );
  410.         } else {
  411.             g.drawLine( right, 6, right, bottom );
  412.         }
  413.  
  414.         // Paint bottom
  415.         if ( tabIndex == lastIndex ) {
  416.             g.drawLine( 0, bottom, right, bottom );
  417.         }
  418.  
  419.         g.translate( -x, -y );
  420.     }
  421.  
  422.  
  423.     protected void paintTabBackground( Graphics g, JTabbedPane pane, int tabPlacement,
  424.                                        int tabIndex, int x, int y, int w, int h, boolean isSelected ) {
  425.         int slantWidth = h / 2;
  426.         if ( isSelected ) {
  427.             g.setColor( selectColor );
  428.         } else {
  429.             g.setColor( pane.getBackgroundAt( tabIndex ) );
  430.         }
  431.         switch ( tabPlacement ) {
  432.         case LEFT:
  433.             g.fillRect(x + 5, y + 1, w - 5, h - 1);
  434.             g.fillRect( x + 2, y + 4, 3, h - 4 );
  435.             break;
  436.         case BOTTOM:
  437.             g.fillRect( x + 2, y, w - 2, h - 3 );
  438.             g.fillRect( x + 5, (y + (h - 1)) - 3, w - 5, 3 );
  439.             break;
  440.         case RIGHT:
  441.             g.fillRect(x + 1, y + 1, w - 5, h - 1);
  442.             g.fillRect( (x+(w-1)) - 3, y+5, 3, h - 1 );
  443.             break;
  444.         case TOP:
  445.         default:  
  446.             g.fillRect( x + 4, y + 2, (w - 1) - 3, (h - 1) - 1 );
  447.             g.fillRect( x + 2, y + 5, 2, h - 5 );
  448.         }
  449.     }
  450.  
  451.  
  452.     protected Insets getTabAreaInsets( JTabbedPane pane, int tabPlacement ) {
  453.         Insets insets;
  454.         switch ( tabPlacement ) {
  455.         case LEFT:
  456.             insets = tabsOnLeftTabAreaInsets;
  457.             break;
  458.         case BOTTOM:
  459.             insets = tabsOnBottomTabAreaInsets;
  460.             break;
  461.         case RIGHT:
  462.             insets = tabsOnRightTabAreaInsets;
  463.             break;
  464.         case TOP:
  465.         default:
  466.             insets = tabsOnTopTabAreaInsets;
  467.         }
  468.         return insets;
  469.     }
  470.  
  471.  
  472.     /**
  473.      * Overidden to do nothing for the Java L&F.
  474.      */
  475.     protected int calculateXNudge( JTabbedPane pane, int tabPlacement, 
  476.                                    int tabIndex, boolean isSelected ) {
  477.         return 0; 
  478.     }
  479.  
  480.  
  481.     /**
  482.      * Overidden to do nothing for the Java L&F.
  483.      */
  484.     protected int calculateYNudge( JTabbedPane pane, int tabPlacement, 
  485.                                    int tabIndex, boolean isSelected ) {
  486.         return 0; 
  487.     }
  488.  
  489.  
  490.     public void paint( Graphics g, JComponent c ) {
  491.         JTabbedPane pane = (JTabbedPane)c;
  492.         int tabPlacement = pane.getTabPlacement();
  493.  
  494.         Insets insets = c.getInsets();
  495.         Dimension size = c.getSize();
  496.  
  497.         // Paint the background for the tab area
  498.         if ( pane.isOpaque() ) {
  499.             g.setColor( c.getBackground() );
  500.             switch ( tabPlacement ) {
  501.             case LEFT:
  502.                 g.fillRect( insets.left, insets.top, 
  503.                             totalTabWidth( pane, tabPlacement, runCount ),
  504.                             size.height - insets.bottom - insets.top );
  505.                 break;
  506.             case BOTTOM:
  507.                 int totalTabHeight = totalTabHeight( pane, tabPlacement, runCount );
  508.                 g.fillRect( insets.left, size.height - insets.bottom - totalTabHeight, 
  509.                             size.width - insets.left - insets.right,
  510.                             totalTabHeight );
  511.                 break;
  512.             case RIGHT:
  513.                 int totalTabWidth = totalTabWidth( pane, tabPlacement, runCount );
  514.                 g.fillRect( size.width - insets.right - totalTabWidth,
  515.                             insets.top, totalTabWidth, 
  516.                             size.height - insets.top - insets.bottom );
  517.                 break;
  518.             case TOP:
  519.             default:
  520.                 g.fillRect( insets.left, insets.top, 
  521.                             size.width - insets.right - insets.left, 
  522.                             totalTabHeight(pane, tabPlacement, runCount) );
  523.                 paintHighlightBelowTab( pane );
  524.             }
  525.         }
  526.  
  527.         super.paint( g, c );
  528.     }
  529.  
  530.     protected void paintHighlightBelowTab( JTabbedPane pane ) {
  531.  
  532.     }
  533.  
  534.  
  535.     protected void paintFocusIndicator(Graphics g, JTabbedPane pane, int tabPlacement,
  536.                                        Rectangle[] rects, int tabIndex, 
  537.                                        Rectangle iconRect, Rectangle textRect,
  538.                                        boolean isSelected) {
  539.         if ( pane.hasFocus() && isSelected ) {
  540.             Rectangle tabRect = rects[tabIndex];
  541.             g.setColor( focus );
  542.             g.translate( tabRect.x, tabRect.y );
  543.             int right = tabRect.width - 1;
  544.             int bottom = tabRect.height - 1;
  545.             switch ( tabPlacement ) {
  546.             case RIGHT:
  547.                 g.drawLine( right - 6,2 , right - 2,6 );         // slant
  548.                 g.drawLine( 1,2 , right - 6,2 );                 // top
  549.                 g.drawLine( right - 2,6 , right - 2,bottom );    // right
  550.                 g.drawLine( 1,2 , 1,bottom );                    // left
  551.                 g.drawLine( 1,bottom , right - 2,bottom );       // bottom
  552.                 break;
  553.             case BOTTOM:
  554.                 g.drawLine( 2,bottom - 6 , 6,bottom - 2 );       // slant
  555.                 g.drawLine( 6,bottom - 2 , right,bottom - 2 );   // bottom
  556.                 g.drawLine( 2,0 , 2,bottom - 6 );                // left
  557.                 g.drawLine( 2,0 , right,0 );                     // top
  558.                 g.drawLine( right,0 , right,bottom - 2 );        // right
  559.                 break;
  560.             case TOP:
  561.             case LEFT:
  562.             default:
  563.                 g.drawLine( 2,6 , 6,2 );                         // slant
  564.                 g.drawLine( 2,6 , 2,bottom - 1);                 // left
  565.                 g.drawLine( 6,2 , right,2 );                     // top
  566.                 g.drawLine( right,2 , right,bottom - 1 );        // right
  567.                 g.drawLine( 2,bottom - 1 , right, bottom - 1 );  // bottom
  568.             }
  569.             g.translate( -tabRect.x, -tabRect.y );
  570.         }
  571.     }
  572.  
  573.  
  574.     protected void paintContentBorderTopEdge( Graphics g, int tabPlacement,
  575.                                               int selectedIndex,
  576.                                               int x, int y, int width, int height ) {    
  577.         g.setColor( tabDarkShadow );
  578.         g.drawLine(x-1, y, width-2, y);
  579.     }
  580.  
  581.  
  582.     protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
  583.                                                 int selectedIndex,
  584.                                                 int x, int y, int w, int h) { 
  585.         g.setColor( tabDarkShadow );
  586.         g.drawLine( x, y+(h-1), x+(w-1), y+(h-1) );
  587.     }
  588.  
  589.     protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
  590.                                               int selectedIndex,
  591.                                               int x, int y, int w, int h) { 
  592.         g.setColor( tabDarkShadow );
  593.         g.drawLine( x, y, x, y+(h-1) );
  594.     }
  595.  
  596.     protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
  597.                                                int selectedIndex,
  598.                                                int x, int y, int w, int h) {
  599.         g.setColor( tabDarkShadow );
  600.         g.drawLine( x+(w-1), y, x+(w-1), y+(h-1) );
  601.     }
  602.  
  603.     protected int maxTabHeight( JTabbedPane pane, FontMetrics metrics ) {
  604.         int height = metrics.getHeight();
  605.         boolean tallerIcons = false;
  606.  
  607.         for ( int i = 0; i < pane.getTabCount(); ++i ) {
  608.             Icon icon = pane.getIconAt( i );
  609.             if ( icon != null ) {
  610.                 if ( icon.getIconHeight() > height ) {
  611.                     tallerIcons = true;
  612.                     break;
  613.                 }
  614.             }
  615.         }
  616.         return super.maxTabHeight( pane, metrics ) - (tallerIcons ? (spacingHeight * 2) : 0);
  617.     }
  618.  
  619.  
  620.     protected int getTabOverlay( JTabbedPane pane, int tabPlacement ) {
  621.         // Tab runs layed out vertically should overlap
  622.         // at least as much as the largest slant
  623.         if ( tabPlacement == LEFT || tabPlacement == RIGHT ) {
  624.             int maxTabHeight = maxTabHeight(pane);
  625.             return maxTabHeight / 2;
  626.         }
  627.         return 0;
  628.     }
  629.  
  630.  
  631.     protected void normalizeTabRuns( JTabbedPane pane, int tabPlacement, int tabCount, 
  632.                                      int start, int max ) {
  633.         // Only normalize the runs for top & bottom;  normalizing
  634.         // doesn't look right for Metal's vertical tabs
  635.         // because the last run isn't padded and it looks odd to have
  636.         // fat tabs in the first vertical runs, but slimmer ones in the
  637.         // last (this effect isn't noticable for horizontal tabs).
  638.         if ( tabPlacement == TOP || tabPlacement == BOTTOM ) {
  639.             super.normalizeTabRuns(pane, tabPlacement, tabCount, start, max);
  640.         }
  641.     }
  642.  
  643.  
  644.     // Don't rotate runs!
  645.     protected void rotateTabRuns( JTabbedPane pane, int tabPlacement, int selectedRun ) {
  646.     }
  647.  
  648.  
  649.     // Don't pad last run
  650.     protected boolean shouldPadRun( JTabbedPane pane, int tabPlacement, int run ) {
  651.         return runCount > 1 && run < runCount - 1;
  652.     }
  653.  
  654.  
  655.     // Don't pad selected tab
  656.     protected void padSelectedTab( JTabbedPane pane, int tabPlacement, int selectedIndex ) {
  657.     }
  658.  
  659. }
  660.  
  661.